﻿using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Tsanie.Common;
using System.Text;
using System.Json;
using System.Collections.Generic;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Views.Animations;
using Android.Views.InputMethods;

namespace Wallpaper
{
    [Activity(Label = "@string/ApplicationName", MainLauncher = true, Icon = "@drawable/icon", Theme = "@style/WallpaperFullScreen")]
    public class MainActivity : Activity
    {
        const string SAVE_STATE_MAIN = "org.tsanie.Wallpaper.list_preview";

        public const int NOTIFICATION_DOWNLOAD = 0;

        EditText editSearch;
        ProgressBar loading;
        PreviewListView listPreview;
        PreviewListAdapter adapter;

        Notification notification;
        NotificationManager manager;

        bool loadingMore = false;
        int lastPage = 1;
        string tag;

        public bool LoadingMore { get { return loadingMore; } }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.main);

            // Get elements from the layout resource,
            loading = FindViewById<ProgressBar>(Resource.Id.progressBar1);
            editSearch = FindViewById<EditText>(Resource.Id.editSearch);
            editSearch.KeyPress += (o, key) =>
            {
                if (key.KeyCode == Keycode.Enter)
                {
                    InputMethodManager imm = (InputMethodManager)GetSystemService(InputMethodService);
                    if (imm.IsActive)
                    {
                        imm.HideSoftInputFromWindow(editSearch.ApplicationWindowToken, HideSoftInputFlags.None);
                    }
                    tag = editSearch.Text;
                    // refresh
                    new CommonTask<bool, bool, JsonArray>
                    {
                        Runner = delegate
                        {
                            return getPreviewDatas(1);
                        },
                        Poster = result =>
                        {
                            adapter.Read(result);
                        }
                    }.Execute();
                    key.Handled = true;
                }
                else
                {
                    key.Handled = false;
                }
            };
            FindViewById<ImageButton>(Resource.Id.buttonSearch).Click += delegate
            {
                if (editSearch.Visibility == ViewStates.Gone)
                {
                    editSearch.Visibility = ViewStates.Visible;
                }
                else
                {
                    editSearch.Visibility = ViewStates.Gone;
                }
            };

            GridLayout root = FindViewById<GridLayout>(Resource.Id.main_root);
            listPreview = new PreviewListView(this);
            var lp = new GridLayout.LayoutParams();
            lp.Width = GridLayout.LayoutParams.MatchParent;
            lp.Height = GridLayout.LayoutParams.MatchParent;
            root.AddView(listPreview, lp);
            listPreview.Refreshed += listPreview_Refreshed;
            listPreview.ItemLongClick += listPreview_ItemLongClick;
            

            if (bundle != null && bundle.ContainsKey(SAVE_STATE_MAIN))
            {
                adapter = (PreviewListAdapter)bundle.GetSerializable(SAVE_STATE_MAIN);
                loading.Visibility = ViewStates.Gone;
                listPreview.Adapter = adapter;
                listPreview.SetOnScrollListener(adapter);
            }
        }

        public override void OnWindowFocusChanged(bool hasFocus)
        {
            if (hasFocus && adapter == null)
            {
                new CommonTask<bool, bool, bool>
                {
                    Runner = loadPreviews,
                    Poster = afterLoadPreviews
                }.Execute();
            }
        }

        #region - load previews -

        JsonArray getPreviewDatas(int page)
        {
            lastPage = page;
            try
            {
                byte[] result = new NetUtility
                {
                    URL = string.Format("https://yande.re/post.json?page={0}&limit=12&tags={1}", page, tag)
                }.GetData();
                string json = Encoding.UTF8.GetString(result);
                result = null;
                return (JsonArray)JsonValue.Parse(json);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return new JsonArray();
            }
        }

        void listPreview_Refreshed(object sender, EventArgs e)
        {
            JsonArray result = getPreviewDatas(1);
            listPreview.Post(delegate
            {
                adapter.Read(result);
            });
        }

        bool loadPreviews(bool[] obj)
        {
            JsonArray result = getPreviewDatas(1);
            adapter = new PreviewListAdapter(result, this);
            return true;
        }

        void afterLoadPreviews(bool result)
        {
            listPreview.Adapter = adapter;
            listPreview.SetOnScrollListener(adapter);
            AlphaAnimation alpha = new AlphaAnimation(1, 0);
            alpha.Duration = Resources.GetInteger(Android.Resource.Integer.ConfigShortAnimTime);
            alpha.AnimationEnd += delegate { loading.Visibility = ViewStates.Gone; };
            loading.StartAnimation(alpha);
        }

        public void LoadMorePreviews()
        {
            if (loadingMore)
            {
                return;
            }
            loadingMore = true;

            new CommonTask<bool, bool, JsonArray>
            {
                Runner = loadMorePreviews,
                Poster = afterLoadMorePreviews
            }.Execute();
        }

        JsonArray loadMorePreviews(bool[] o)
        {
            return getPreviewDatas(lastPage + 1);
        }

        void afterLoadMorePreviews(JsonArray result)
        {
            adapter.Add(result);

            loadingMore = false;
        }

        #endregion

        #region - download picture -

        void listPreview_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
        {
            if (notification != null)
            {
                Toast.MakeText(this, "不要着急，一个一个下。", ToastLength.Short).Show();
                return;
            }

            notification = new Notification(Resource.Drawable.icon, "开始下载", Java.Lang.JavaSystem.CurrentTimeMillis());
            notification.Flags = NotificationFlags.OngoingEvent | NotificationFlags.NoClear;
            var picture = adapter.Pictures[e.Position - 1];
            string filename = picture["file_url"];
            filename = filename.Substring(filename.LastIndexOf('/') + 1);
            notification.ContentView = getDownloadView(filename, 0, 0);

            manager = ((NotificationManager)GetSystemService(Context.NotificationService));
            manager.Notify(NOTIFICATION_DOWNLOAD, notification);
            new CommonTask<JsonValue, object, bool>
            {
                Runner = downloadPicture,
                Poster = afterDownloadPicture
            }.Execute(picture);
        }

        RemoteViews getDownloadView(string file, int total, int position)
        {
            var view = new RemoteViews(PackageName, Resource.Layout.notification);
            view.SetTextViewText(Resource.Id.textNotificationFile, file);
            view.SetProgressBar(Resource.Id.progressDownloader, total, position, total == 0);
            return view;
        }

        bool downloadPicture(JsonValue[] o)
        {
            bool result = false;
            if (o != null && o.Length > 0)
            {
                JsonValue picture = o[0];
                int length = (int)picture["file_size"];
                if (Android.OS.Environment.MediaMounted == Android.OS.Environment.ExternalStorageState)
                {
                    string filename = picture["file_url"];
                    filename = filename.Substring(filename.LastIndexOf('/') + 1);
                    byte[] data = new NetUtility
                    {
                        URL = picture["file_url"],
                        Step = pos =>
                        {
                            notification.ContentView = getDownloadView(filename, length, (int)pos);
                            manager.Notify(NOTIFICATION_DOWNLOAD, notification);
                        }
                    }.GetData();

                    Java.IO.File sdcardDir = Android.OS.Environment.ExternalStorageDirectory;
                    string path = sdcardDir.Path + "/Android/data/org.tsanie.Wallpaper_data/images";
                    Java.IO.File path1 = new Java.IO.File(path);
                    if (!path1.Exists())
                    {
                        path1.Mkdirs();
                    }

                    // save
                    using (var writer = new System.IO.FileStream(path + "/" + filename, System.IO.FileMode.Create))
                    {
                        writer.Write(data, 0, data.Length);
                        writer.Flush();
                    }
                    result = true;
                }

                manager.Cancel(NOTIFICATION_DOWNLOAD);
                notification = null;
            }

            return result;
        }

        void afterDownloadPicture(bool result)
        {
            if (result)
            {
                Toast.MakeText(this, "下载完成", ToastLength.Long).Show();
            }
            else
            {
                Toast.MakeText(this, "无法写入sd卡", ToastLength.Long).Show();
            }
        }

        #endregion
    }
}

